﻿using Gameplay.PVE.Utils;
using System;
using System.Collections.Generic;
using ImageEffects;
using UnityEngine;
using UnityEngine.UI;
using Yoozoo.Framework.Managers;
using AudioStudio;
using XLua;
using Yoozoo.Gta.Common;

namespace Gameplay.PVE
{
    public class DeckManager
    {
        private static DeckManager instance;

        public static DeckManager Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new DeckManager();
                }

                return instance;
            }
        }

        public Dictionary<int, ModelDrag> heroToDragDict = new Dictionary<int, ModelDrag>();
        public ModelDrag curModelDrag;
        public bool isDragging = false;

        //英雄id - 位置id：40002 - 1
        private Dictionary<int, int> heroToDeckPosDict = new Dictionary<int, int>();

        //英雄id - 模型 GameObject
        private Dictionary<int, GameObject> modelDict = new Dictionary<int, GameObject>();

        private Dictionary<int, GameObject> monsterModelDict = new Dictionary<int, GameObject>();
        private Dictionary<int, int> monsterIndexToModelDict = new Dictionary<int, int>();
        private Dictionary<int, GameObject> monsterIndexToLevevlObjDict = new Dictionary<int, GameObject>();
        private Dictionary<int, float> monsterOriginScale = new Dictionary<int, float>();
        
        //英雄id - 模型id：400002 - 996
        private Dictionary<int, int> heroToModelDict = new Dictionary<int, int>();

        //存储布阵底部光圈游戏物体的引用
        private List<GameObject> deckCircleList = new List<GameObject>();

        private List<DeckCircleController> deckCircleControllerList = new List<DeckCircleController>();
        
        //存储初始布阵列表，判断布阵是否有变化
        private Dictionary<int, int> initHeroToDeckPosDict = new Dictionary<int, int>();
        
        private Vector3 modelOffset = new Vector3(0, 0.8f, 0);
        
        private Vector3[] deckCirclePosArray = new[]
        {
            new Vector3(133.1f, 0.01f, 83.66f),
            new Vector3(133.1f, 0.01f, 80.39f),
            new Vector3(130.44f, 0.01f, 84.6f),
            new Vector3(130.4f, 0.01f, 82.08f),
            new Vector3(130.42f, 0.01f, 79.58f),
        };
        
        private Vector3[] deckCirclePosArrayFromUI = new[]
        {
            new Vector3(133.1f, 0.01f, 83.66f),
            new Vector3(133.1f, 0.01f, 80.39f),
            new Vector3(130.44f, 0.01f, 84.6f),
            new Vector3(130.4f, 0.01f, 82.08f),
            new Vector3(130.42f, 0.01f, 79.58f),
        };
        
        //记录5个点位是否有空位
        private int[] hasDeckSpace = new int[]
        {
            -1,
            -1,
            -1,
            -1,
            -1,
        };

        //记录所有模型加载完成的回调，在加载完成后统一调用
        private List<ModelLoadInfo> onAllModelLoaded = new List<ModelLoadInfo>();

        private class ModelLoadInfo
        {
            public int HeroId;
            public int MonsterIndex;
            public Action onModelLoaded; //模型加载完成的回调
        }

        private string sHeroVoice = "";
        private GameObject lastPlayVoiceObj = null;

        public void Update()
        {
            //更新保存按键状态
            ResidentHandler.Inst.GetFunction("pveManager.ShowDeckSaveBtn").Action(HasHeroesChanged());

            //如果正在拖动，则只执行拖动物体的Update
            if (isDragging)
            {
                curModelDrag.OnUpdate();
                return;
            }
            //遍历所有物体，判断是否有被拖动的
            foreach (var drag in heroToDragDict)
            {
                drag.Value.OnUpdate();
                if (isDragging)
                {
                    break;
                }
            }
        }

        [LuaCallCSharp]
        public void Init(bool isToRpg = true)
        {
            var playerBirthPositions = PveUtils.GetRpgPlayerBirthPositions();
            var center = PveManager.Instance.GetRpgStageCenterPosition();
            for (int i = 0; i < deckCirclePosArray.Length; i++)
            {
                //初始化生成五个布阵点位
                GameObject obj = PveResourceManager.GetResource(PveResourceManager.EPveResType.Hud, 17);
                obj.SetActive(true);
                obj.transform.SetParent(PveScene.pveRootTrans);

                Vector3 position;
                if (playerBirthPositions.TryGetValue(i, out position) && isToRpg)
                {
                    deckCirclePosArray[i] = position + center;
                }
                else
                {
                    deckCirclePosArray[i] = deckCirclePosArrayFromUI[i];
                }
                obj.transform.localPosition =  deckCirclePosArray[i];
                obj.transform.localRotation = Quaternion.Euler(90, 0, 0);
                obj.transform.localScale = 1.3f * Vector3.one;
                obj.GetComponentInChildren<Image>().color = Color.white;
                Animation ani = obj.GetComponentInChildren<Animation>();
                if (ani)
                {
                    ani.Stop();
                    ani.Play("ani_sfx_buzheng_resid");
                }
                deckCircleList.Add(obj);
                var controller = obj.GetComponent<DeckCircleController>();
                controller.SetHeroState(false);
                deckCircleControllerList.Add(controller);
            }

            /*var center = PveManager.Instance.GetRpgStageCenterPosition();
            //敌方的点位
            for (int i = 0; i < deckCirclePosArray.Length; i++)
            {
                //初始化生成五个布阵点位
                GameObject obj = PveResourceManager.GetResource(PveResourceManager.EPveResType.Hud, 17);
                obj.SetActive(true);
                obj.transform.SetParent(PveScene.pveRootTrans);
                obj.transform.localPosition = new Vector3(center.x * 2,0,center.z) - deckCirclePosArray[i];
                obj.transform.localRotation = Quaternion.Euler(90, 0, 0);
                obj.transform.localScale = 1.3f * Vector3.one;
                obj.GetComponentInChildren<Image>().color = Color.white;
                Animation ani = obj.GetComponentInChildren<Animation>();
                if (ani)
                {
                    ani.Stop();
                    ani.Play("ani_sfx_buzheng_resid");
                }
                deckCircleList.Add(obj);
            }*/
        }

        
        
        //从外部拿取模型
        public GameObject GetHeroModel(int heroId)
        {
            return ResidentHandler.Inst.GetFunction("L_RpgManager.GetHeroFromDeck").Func<int, GameObject>(heroId);
            if (modelDict.TryGetValue(heroId, out var gameObject))
            {
                modelDict.Remove(heroId);
                return gameObject;
            }
            return null;
        }

        public GameObject GetMonsterModel(int monsterIndex)
        {
            return ResidentHandler.Inst.GetFunction("L_RpgManager.GetMonsterFromDeck").Func<int, GameObject>(monsterIndex);
            if (monsterModelDict.TryGetValue(monsterIndex,out var gameObject))
            {
                monsterModelDict.Remove(monsterIndex);
                gameObject.transform.localScale = monsterOriginScale[monsterIndex] * Vector3.one;
                return gameObject;
            }
            return null;
        }

        public void RpgEnd()
        {
            ClearModel();
        }

        private void ClearBase()
        {
            for (int i = 0; i < hasDeckSpace.Length; i++)
            {
                hasDeckSpace[i] = -1;
            }
            foreach (var item in modelDict)
            {
                var modelDrag = modelDict[item.Key].GetComponent<ModelDrag>();
                if (modelDrag != null)
                {
                    //获取等级条的引用并回收
                    var levelObj = modelDrag.levelObj;
                    if (levelObj != null)
                    {
                        var images = levelObj.GetComponentsInChildren<Image>();
                        foreach (var image in images)
                        {
                            image.enabled = false;
                        }
                        PveResourceManager.RecoverResource(levelObj, PveResourceManager.EPveResType.Hud, 18);
                    }
                }
                UnityEngine.Object.Destroy(modelDrag);
            }
            foreach (var item in monsterIndexToLevevlObjDict)
            {
                PveResourceManager.RecoverResource(item.Value, PveResourceManager.EPveResType.Hud, 18);
            }
            monsterIndexToLevevlObjDict.Clear();
            foreach (var item in deckCircleList)
            {
                PveResourceManager.RecoverResource(item, PveResourceManager.EPveResType.Hud, 17);
            }
            deckCircleControllerList.Clear();
            heroToDragDict.Clear();
            initHeroToDeckPosDict.Clear();
            deckCircleList.Clear();
            heroToDeckPosDict.Clear();
            onAllModelLoaded.Clear();
        }

        private void ClearModel()
        {
            foreach (var item in modelDict)
            {
                PveResourceManager.RecoverResource(item.Value, PveResourceManager.EPveResType.Model, heroToModelDict[item.Key]);
            }
            modelDict.Clear();
            foreach (var item in monsterModelDict)
            {
                var obj = item.Value;
                obj.transform.localScale = monsterOriginScale[item.Key] * Vector3.one;
                PveResourceManager.RecoverResource(item.Value, PveResourceManager.EPveResType.Model, monsterIndexToModelDict[item.Key]);
            }
            monsterOriginScale.Clear();
            monsterModelDict.Clear();
            heroToModelDict.Clear();
            monsterIndexToModelDict.Clear();
        }
        
        [LuaCallCSharp]
        public void DeckToRpg()
        {
            ClearBase();
        }

        
        public void DeckToPve()
        {
            ClearBase();
            ClearModel();
            /*for (int i = 0; i < hasDeckSpace.Length; i++)
            {
                hasDeckSpace[i] = -1;
            }
            foreach (var item in modelDict)
            {
                //回收所有模型
                PveResourceManager.RecoverResource(item.Value, PveResourceManager.EPveResType.Model, heroToModelDict[item.Key]);
                var modelDrag = modelDict[item.Key].GetComponent<ModelDrag>();
                if (modelDrag != null)
                {
                    //获取等级条的引用并回收
                    var levelObj = modelDrag.levelObj;
                    if (levelObj != null)
                    {
                        var images = levelObj.GetComponentsInChildren<Image>();
                        foreach (var image in images)
                        {
                            image.enabled = false;
                        }
                        PveResourceManager.RecoverResource(levelObj, PveResourceManager.EPveResType.Hud, 18);
                    }
                }
                UnityEngine.Object.Destroy(modelDrag);
            }
            modelDict.Clear();

            foreach (var item in monsterModelDict)
            {
                PveResourceManager.RecoverResource(item.Value, PveResourceManager.EPveResType.Model, monsterIndexToModelDict[item.Key]);
            }
            monsterModelDict.Clear();
            foreach (var item in monsterIndexToLevevlObjDict)
            {
                PveResourceManager.RecoverResource(item.Value, PveResourceManager.EPveResType.Hud, 18);
            }
            monsterIndexToLevevlObjDict.Clear();
            foreach (var item in deckCircleList)
            {

                PveResourceManager.RecoverResource(item, PveResourceManager.EPveResType.Hud, 17);
            }
            heroToModelDict.Clear();
            heroToDragDict.Clear();
            initHeroToDeckPosDict.Clear();
            deckCircleList.Clear();
            heroToDeckPosDict.Clear();
            onAllModelLoaded.Clear();*/
        }

 

        public void LoadDeckModel()
        {
            /*PveResourceManager.Instance.StartLoad(() =>
            {
                foreach (var info in onAllModelLoaded)
                {
                    info.onModelLoaded?.Invoke();
                }
                onAllModelLoaded.Clear();
            });*/
        }

        public void SetMonsterDeckModel(int modelId, int level, int monsterIndex,Vector3 position,float scale = 1)
        {
            monsterIndexToModelDict[monsterIndex] = modelId;
            monsterOriginScale[monsterIndex] = 1;
            //加载模型
            if (!PveResourceManager.IsResReady(PveResourceManager.EPveResType.Model, modelId))
            {
                GameObject renderer = null;
                //加载完成前，先显示加载效果预制体
                GameObject loadingObj = PveResourceManager.GetResource(PveResourceManager.EPveResType.Hud, 19);
                SetMonsterLoadingRenderer(loadingObj, monsterIndex,position);
                //加载英雄模型
                var info = new ModelLoadInfo()
                {
                    MonsterIndex = monsterIndex,
                    onModelLoaded = () =>
                    {
                        renderer = PveResourceManager.GetResource(PveResourceManager.EPveResType.Model, modelId);

                        var le = renderer.GetComponent<LightElement>();
                        if (le)
                        {
                            PveMap.rpgLightController.AddLightElement(le);
                        }

                        SetMonsterModelRenderer(renderer, position,monsterIndex);
                        renderer.transform.localPosition = loadingObj.transform.localPosition - modelOffset;
                        var localScale = renderer.transform.localScale;
                        monsterOriginScale[monsterIndex] = localScale.x;
                        localScale = scale * localScale;
                        renderer.transform.localScale = localScale;
                        var levelObj = SetLevelUI(level, renderer);
                        monsterIndexToLevevlObjDict[monsterIndex] = levelObj;
                        PveResourceManager.RecoverResource(loadingObj, PveResourceManager.EPveResType.Hud, 19);
                        RemoveFromLoadingActionsMonster(monsterIndex);
                    }
                };
                onAllModelLoaded.Add(info);
                PveResourceManager.Instance.LoadDeckHero(modelId, ()=> { DoLoadingActionMonster(monsterIndex); });
            }
            else
            {
                GameObject renderer = PveResourceManager.GetResource(PveResourceManager.EPveResType.Model, modelId);
                SetMonsterModelRenderer(renderer,position,monsterIndex);
                var levelObj = SetLevelUI(level, renderer);
                monsterIndexToLevevlObjDict[monsterIndex] = levelObj;
                var localScale = renderer.transform.localScale;
                monsterOriginScale[monsterIndex] = localScale.x;
                localScale = scale * localScale;
                renderer.transform.localScale = localScale;
                var le = renderer.GetComponent<LightElement>();
                if (le)
                {
                    PveMap.rpgLightController.AddLightElement(le);
                }
            }
        }
        
        public void SetDeckModel(int modelId, int level, int heroId,string heroVioce, int sort = -1)
        {
            heroToModelDict[heroId] = modelId;
            //获取模型生成的位置
            int nextPosIndex = 0;
            bool bPlace = false;
            if (sort != -1)
            {
                //读取服务器上次保存的数据
                sort--; //点位从1开始计数，数组从0开始
                hasDeckSpace[sort] = heroId;
                nextPosIndex = sort;
                initHeroToDeckPosDict[heroId] = sort;
                PveUtils.deckHeroes.Add(heroId);
                PveUtils.deckHeroInfo[heroId] = sort;
                RefreshSingleColor(sort);
            }
            else
            {
                nextPosIndex = GetNextDeckPos(heroId);
                // 新增播放特效
                bPlace = true;
            }
            
            heroToDeckPosDict[heroId] = nextPosIndex;
            
            //加载模型
            if (!PveResourceManager.IsResReady(PveResourceManager.EPveResType.Model, modelId))
            {
                GameObject renderer = null;
                //加载完成前，先显示加载效果预制体
                GameObject loadingObj = PveResourceManager.GetResource(PveResourceManager.EPveResType.Hud, 19);
                SetLoadingRenderer(loadingObj, heroId, nextPosIndex);
                //加载英雄模型
                var info = new ModelLoadInfo()
                {
                    HeroId = heroId,
                    onModelLoaded = () =>
                    {
                        //PveResourceManager.LoadResource(PveResourceManager.EPveResType.Model, modelId, o => { });
                        renderer = PveResourceManager.GetResource(PveResourceManager.EPveResType.Model, modelId);

                        var le = renderer.GetComponent<LightElement>();
                        if (le)
                        {
                            PveMap.rpgLightController.AddLightElement(le);
                        }

                        var modelDrag = SetModelRenderer(renderer, heroId, nextPosIndex,bPlace);
                        renderer.transform.localPosition = loadingObj.transform.localPosition - modelOffset;
                        var levelObj = SetLevelUI(level, renderer, heroId);
                        modelDrag.levelObj = levelObj;
                        PveResourceManager.RecoverResource(loadingObj, PveResourceManager.EPveResType.Hud, 19);
                        PlayHeroComeVoice(heroVioce, modelDrag.gameObject);
                        RemoveFromLoadingActions(heroId);
                    }
                };
                onAllModelLoaded.Add(info);
                PveResourceManager.Instance.LoadDeckHero(modelId, ()=> { DoLoadingAction(heroId); });
            }
            else
            {
                GameObject renderer = PveResourceManager.GetResource(PveResourceManager.EPveResType.Model, modelId);
                var modelDrag = SetModelRenderer(renderer, heroId, nextPosIndex,bPlace);
                var levelObj = SetLevelUI(level, renderer, heroId);
                modelDrag.levelObj = levelObj;
                
                var le = renderer.GetComponent<LightElement>();
                if (le)
                {
                    PveMap.rpgLightController.AddLightElement(le);
                }
                PlayHeroComeVoice(heroVioce, modelDrag.gameObject);
            }
        }

        // 播放英雄出场声音
        private void PlayHeroComeVoice(string heroVioce,GameObject obj)
        {
            if (sHeroVoice.Length > 0 && lastPlayVoiceObj)
            {
                AudioManager.StopVoice(sHeroVoice, 0, lastPlayVoiceObj);
            }
            if (heroVioce.Length > 0)
            {
                AudioManager.PlayVoice(heroVioce, obj);
                sHeroVoice = heroVioce;
                lastPlayVoiceObj = obj;
            }
        }

        private void RemoveFromLoadingActions(int heroId)
        {
            for (int i = 0; i < onAllModelLoaded.Count; i++)
            {
                if (onAllModelLoaded[i].HeroId == heroId)
                {
                    onAllModelLoaded.RemoveAt(i);
                    break;
                }
            }
        }
        
        private void RemoveFromLoadingActionsMonster(int monsterIndex)
        {
            for (int i = 0; i < onAllModelLoaded.Count; i++)
            {
                if (onAllModelLoaded[i].MonsterIndex == monsterIndex)
                {
                    onAllModelLoaded.RemoveAt(i);
                    break;
                }
            }
        }

        private void DoLoadingAction(int heroId)
        {
            for (int i = 0; i < onAllModelLoaded.Count; i++)
            {
                if (onAllModelLoaded[i].HeroId == heroId)
                {
                    onAllModelLoaded[i].onModelLoaded?.Invoke();
                    break;
                }
            }
        }
        
        private void DoLoadingActionMonster(int monsterIndex)
        {
            for (int i = 0; i < onAllModelLoaded.Count; i++)
            {
                if (onAllModelLoaded[i].MonsterIndex == monsterIndex)
                {
                    onAllModelLoaded[i].onModelLoaded?.Invoke();
                }
            }
        }
        
        public void CancelDeckModel(int heroId)
        {
            DeckManager.Instance.PlayCircleAni(heroToDeckPosDict[heroId], "ani_sfx_buzheng_resid_and_out");
            UpdateHasDeckSpace(heroToDeckPosDict[heroId], -1);
            heroToDeckPosDict.Remove(heroId);
            var modelDrag = modelDict[heroId].GetComponent<ModelDrag>();
            //如果处于加载状态时被回收
            if (modelDrag.isLoading)
            {
                PveResourceManager.RecoverResource(modelDict[heroId], PveResourceManager.EPveResType.Hud, 19);
                //不再执行模型加载完成后的回调
                RemoveFromLoadingActions(modelDrag.HeroId);
            }
            else
            {
                PveResourceManager.RecoverResource(modelDrag.levelObj, PveResourceManager.EPveResType.Hud, 18);
                PveResourceManager.RecoverResource(modelDict[heroId], PveResourceManager.EPveResType.Model, heroToModelDict[heroId]);
                var levelObj = modelDrag.levelObj;
                var images = levelObj.GetComponentsInChildren<Image>();
                foreach (var image in images)
                {
                    image.enabled = false;
                }
            }
            UnityEngine.Object.Destroy(modelDrag);
            heroToDragDict.Remove(heroId);
            modelDict.Remove(heroId);
        }

        public void HasDeckChanged()
        {
            bool hasHeroes = false;
            foreach (var item in heroToDeckPosDict)
            {
                if (item.Value != -1)
                {
                    hasHeroes = true;
                }
            }

            ResidentHandler.Inst.GetFunction("pveManager.ShowDeckChange").Action( HasHeroesChanged(), hasHeroes);
        }

        public bool HasHeroesChanged()
        {
            bool hasNumChanged = initHeroToDeckPosDict.Count != heroToDeckPosDict.Count;
            bool hasHeroChanged = false;
            foreach (var init in initHeroToDeckPosDict)
            {
                if (!heroToDeckPosDict.ContainsKey(init.Key))
                {
                    hasHeroChanged = true;
                    break;
                }
                if (heroToDeckPosDict[init.Key] != init.Value)
                {
                    hasHeroChanged = true;
                    break;
                }
            }

            return hasNumChanged || hasHeroChanged;
        }

        public void SaveDeckHeroInfo(int showTips)
        {
            int doubtfulId = 1; //布阵id
            //如果没有上阵英雄，传一个-1过去，不进行保存
            if (heroToDeckPosDict.Count == 0)
            {
                ResidentHandler.Inst.GetFunction("pveManager.SaveDeckHeroInfo").Action(doubtfulId, -1);
                return;
            }
            PveUtils.deckHeroes.Clear();
            PveUtils.deckHeroInfo.Clear();
            int[] heroes = {-1, -1, -1, -1, -1};
           
            foreach (var item in heroToDeckPosDict)
            {
                if (item.Value == -1)
                {
                    continue;
                }

                PveUtils.deckHeroes.Add(item.Key);
                int sort = item.Value;
                PveUtils.deckHeroInfo.Add(item.Key, sort);
                heroes[sort] = item.Key;
            }

            //更新初始字典
            initHeroToDeckPosDict = new Dictionary<int, int>(heroToDeckPosDict);
            ResidentHandler.Inst.GetFunction("pveManager.SaveDeckHeroInfo").Action(doubtfulId, heroes, showTips == 1);
        }

        private int GetNextDeckPos(int heroId)
        {
            for (int i = 0; i < hasDeckSpace.Length; i++)
            {
                if (hasDeckSpace[i] < 0)
                {
                    hasDeckSpace[i] = heroId;
                    return i;
                }
            }
            return -1;
        }

        public void SetNullDeckPos()
        {
            foreach (var key in PveUtils.deckHeroInfo.Keys)
            {
                hasDeckSpace[PveUtils.deckHeroInfo[key]] = key;
            }
        }

        // 获得当前布阵是否有空位
        public bool GetNullDeckPos()
        {
            bool bNull = false;
            for (int i = 0; i < hasDeckSpace.Length; i++)
            {
                bNull = bNull || hasDeckSpace[i] < 0;
                if (bNull) break;
            }
            return bNull;
        }

        private void SetMonsterLoadingRenderer(GameObject renderer, int monsterIndex,Vector3 position)
        {
            renderer.transform.localPosition = position + modelOffset;
            renderer.transform.localRotation = Quaternion.Euler(30, 0, 0);
            renderer.transform.localScale = 0.1f * Vector3.one;
            renderer.transform.SetParent(PveScene.pveRootTrans);
            monsterModelDict[monsterIndex] = renderer;
            //设置动画
            Animation animator = renderer.GetComponent<Animation>();
            if (animator != null)
            {
                animator.Play("ani_ui_deckloading");
            }
        }
        
        private void SetLoadingRenderer(GameObject renderer, int heroId, int nextPosIndex)
        {
            //设置模型
            renderer.transform.localPosition = deckCirclePosArray[nextPosIndex] + modelOffset;
            renderer.transform.localRotation = Quaternion.Euler(30, 0, 0);
            renderer.transform.localScale = 0.1f * Vector3.one;
            renderer.transform.SetParent(PveScene.pveRootTrans);
            renderer.AddComponent<BoxCollider>().size = new Vector3(4, 4, 4);
            modelDict[heroId] = renderer;
            //设置拖动脚本
            var modelDrag = renderer.GetOrAddComponent<ModelDrag>();
            modelDrag.HeroId = heroId;
            modelDrag.curPosIdx = nextPosIndex;
            modelDrag.DeckCirclePosArray = deckCirclePosArray;
            modelDrag.isLoading = true;
            heroToDragDict[heroId] = modelDrag;
            //设置动画
            Animation animator = renderer.GetComponent<Animation>();
            if (animator != null)
            {
                animator.Play("ani_ui_deckloading");
            }
        }

        private void SetMonsterModelRenderer(GameObject renderer,Vector3 position,int monsterIndex)
        {
            renderer.transform.SetParent(PveScene.pveRootTrans);
            renderer.transform.localPosition = position;
            renderer.transform.forward = Vector3.left;
            monsterModelDict[monsterIndex] = renderer;
            var renderers = renderer.GetComponentsInChildren<SkinnedMeshRenderer>();
            for (int i = 0; i < renderers.Length; i++)
            {
                var mats = renderers[i].sharedMaterials;
                for (int j = 0; j < mats.Length; j++)
                {
                    var mat = mats[j];
                    if (mat.shader.name.Contains("Shadow"))
                    {
                        mat.SetFloat("_ShadowHeight",0.01f);
                    }
                }
            }
            var meshrenderers = renderer.GetComponentsInChildren<MeshRenderer>();
            for (int i = 0; i < meshrenderers.Length; i++)
            {
                var mats = meshrenderers[i].sharedMaterials;
                for (int j = 0; j < mats.Length; j++)
                {
                    var mat = mats[j];
                    if (mat.shader.name.Contains("Shadow"))
                    {
                        mat.SetFloat("_ShadowHeight",0.01f);
                    }
                }
            }
        }
        
        private ModelDrag SetModelRenderer(GameObject renderer, int heroId, int nextPosIndex,bool bPlace)
        {
            //设置模型
            renderer.transform.localPosition = deckCirclePosArray[nextPosIndex];
            renderer.transform.forward = Vector3.right;
            renderer.transform.SetParent(PveScene.pveRootTrans);

            var renderers = renderer.GetComponentsInChildren<SkinnedMeshRenderer>();
            for (int i = 0; i < renderers.Length; i++)
            {
                var mats = renderers[i].sharedMaterials;
                for (int j = 0; j < mats.Length; j++)
                {
                    var mat = mats[j];
                    if (mat.shader.name.Contains("Shadow"))
                    {
                        mat.SetFloat("_ShadowHeight",0.01f);
                    }
                }
            }
            var meshrenderers = renderer.GetComponentsInChildren<MeshRenderer>();
            for (int i = 0; i < meshrenderers.Length; i++)
            {
                var mats = meshrenderers[i].sharedMaterials;
                for (int j = 0; j < mats.Length; j++)
                {
                    var mat = mats[j];
                    if (mat.shader.name.Contains("Shadow"))
                    {
                        mat.SetFloat("_ShadowHeight",0.01f);
                    }
                }
            }
            
            BoxCollider box = renderer.GetOrAddComponent<BoxCollider>();
            box.center = new Vector3(0, 1, 0);
            box.size = new Vector3(1, 2, 1);
            modelDict[heroId] = renderer;
            //设置拖动脚本
            var modelDrag = renderer.GetOrAddComponent<ModelDrag>();
            modelDrag.HeroId = heroId;
            modelDrag.curPosIdx = nextPosIndex;
            modelDrag.DeckCirclePosArray = deckCirclePosArray;
            modelDrag.isLoading = false;
            heroToDragDict[heroId] = modelDrag;
            //设置动画
            Animator animator = renderer.GetComponent<Animator>();
            if (animator != null)
            {
                animator.enabled = true;
            }
            if (bPlace)
            {
                PlayCircleAni(nextPosIndex, "ani_sfx_buzheng_place");
            }
   
            return modelDrag;
        }

        private GameObject SetLevelUI(int level, GameObject renderer, int heroId = 0)
        {
            GameObject levelObj = PveResourceManager.GetResource(PveResourceManager.EPveResType.Hud, 18);
            levelObj.GetComponentInChildren<Text>().text = "Lv. " + level;
            levelObj.transform.Find("Bg").GetComponent<Image>().enabled = true;
            if (heroId != 0)
            {
                levelObj.transform.Find("Bg/" + CalHeroType(heroId)).GetComponent<Image>().enabled = true;
            }
            levelObj.transform.SetParent(renderer.transform);
            levelObj.transform.localPosition = new Vector3(0, 2f, 0);
            levelObj.transform.eulerAngles = new Vector3(35,0,0);
            //levelObj.transform.forward = -PveCameraManager.Instance.mainCamera.transform.forward;
            levelObj.transform.localScale = 0.15f * Vector3.one;
            return levelObj;
        }

        private string CalHeroType(int heroId)
        {
            var battleConfig = PveUtils.GetExternalHeroConfig(heroId);
            return battleConfig.rpg_feature_icon;
        }

        public void SwitchModelPos(Vector3 modelPos, int heroId)
        {
            for (int i = 0; i < deckCirclePosArray.Length; i++)
            {
                modelPos = new Vector3(modelPos.x, deckCirclePosArray[i].y, modelPos.z);
                if (Vector3.Distance(deckCirclePosArray[i], modelPos) < 1f)
                {
                    Debug.Log(string.Format("[布阵] 更新拖拽模型{0} -> {1}", heroId, i));
                    UpdateDeckHeroPosition(i, heroId);
                   // deckCircleList[i].GetComponentInChildren<Image>().color = Color.white;
                    break;
                }
            }
        }

        // 将heroId的模型设置到curIndex位置
        private void UpdateDeckHeroPosition(int curIndex, int heroId)
        {
            int startIndex = heroToDeckPosDict[heroId];
            if (hasDeckSpace[curIndex] > 0)
            {
                foreach (var item in heroToDeckPosDict)
                {
                    //模型对应的位置索引 == 当前索引
                    if (item.Value == curIndex)
                    {
                        Debug.Log(string.Format("[布阵] 替换{0} -> {1}", startIndex, curIndex));
                        // 还原之前的交换
                        int backIdx = RestoreOldPos(false, curIndex, startIndex);
                        if (backIdx >= 0) startIndex = backIdx;
                        if (startIndex != curIndex) UpdateDeckModelPos(item.Key, startIndex);
                        Debug.Log(string.Format("[布阵] 设置{0} -> {1}", curIndex, startIndex));
                        //更新位置字典
                        heroToDeckPosDict[heroId] = curIndex;
                        heroToDeckPosDict[item.Key] = startIndex;
                        UpdateHasDeckSpace(curIndex, heroId);
                        UpdateHasDeckSpace(startIndex, item.Key);
                        // 设置本次交换记录
                        ModelDrag drag = heroToDragDict[item.Key];
                        drag.curPosIdx = startIndex;
                        if (drag.oldPosIdx < 0 && backIdx >= 0) drag.oldPosIdx = curIndex;
                        break;
                    }
                }
            }
            else
            {
                Debug.Log(string.Format("[布阵] 拖拽{0} -> {1}", startIndex, curIndex));
                // 还原之前的交换
                RestoreOldPos(false, curIndex);
                //如果移动到的地方没有人
                UpdateHasDeckSpace(curIndex, heroId);
                //更新位置字典
                heroToDeckPosDict[heroId] = curIndex;
            }
        }

        public void UpdateDeckModelPos(int heroId,int curIndex)
        {
            Debug.Log(string.Format("[布阵] 设置模型位置 {0} -> {1}",modelDict[heroId].name,curIndex));
            modelDict[heroId].transform.position = deckCirclePosArray[curIndex];
        }

        public void UpdateHeroToDeckPosDict(int heroId, int index)
        {
            heroToDeckPosDict[heroId] = index;
        }

        public void UpdateHasDeckSpace(int index,int heroId = -1)
        {
            for (int i = 0;i < hasDeckSpace.Length;i++)
            {
                if (heroId == hasDeckSpace[i] && i != index)
                {
                    hasDeckSpace[i] = -1;
                }
            }

            if (index >= 0)
            {
                hasDeckSpace[index] = heroId;
            }

            RefreshAllColor();
        }

        public void PrintDeckInfo()
        {
            //string log = "[布阵] 布阵信息: ";
            //for (int i = 0; i < hasDeckSpace.Length; i++)
            //{
            //    log += string.Format("[{0},{1}]|", i, hasDeckSpace[i].ToString());
            //}
            //Debug.Log(log);
        }

        public int RestoreOldPos(bool bClear,int idx = -1,int idx2 = -1)
        {
            int backIdx = idx2;
            foreach (var drag in heroToDragDict.Values)
            {
                if (bClear)// 只清除数据
                {
                    drag.oldPosIdx = -1;
                }
                else if (drag.oldPosIdx >= 0 && drag.oldPosIdx != drag.curPosIdx && drag.isDragging == false)
                {
                    backIdx = drag.curPosIdx;
                    UpdateHasDeckSpace(drag.oldPosIdx, drag.HeroId);
                    Debug.Log(string.Format("[布阵] 还原{0} -> {1}", backIdx, drag.oldPosIdx));
                    if (idx == drag.curPosIdx) backIdx = -1; // 这里要判断是重复交换
                    UpdateDeckModelPos(drag.HeroId, drag.oldPosIdx);
                    drag.curPosIdx = drag.oldPosIdx;
                    drag.oldPosIdx = -1;
                    //更新位置字典
                    heroToDeckPosDict[drag.HeroId] = drag.curPosIdx;
                }
            }
            return backIdx;
        }

        public int UpdateCircle(Vector3 modelPos,int oldPos)
        {
            int newPos = -1;
            for (int i = 0; i < deckCirclePosArray.Length; i++)
            {
                modelPos = new Vector3(modelPos.x, deckCirclePosArray[i].y, modelPos.z);
                if (Vector3.Distance(deckCirclePosArray[i], modelPos) < 1f)
                {
                    newPos = i;
                    break; 
                }
            }
            if (oldPos != newPos)
            {
                PlayCircleAni(newPos, "ani_sfx_buzheng_change");
            }
            return newPos;
        }

        public void ResetCircleColor()
        {
            //PlayCircleAni(-1, "");// 停止所有特效
            for (int i = 0; i < deckCircleControllerList.Count; i++)
            {
                var controller = deckCircleControllerList[i];
                Animation ani = controller.animation;
                bool hasHero = hasDeckSpace[i] >= 0;
                if (ani)
                {
                    ani.Stop();
                    if (hasHero)
                    {
                        ani.Play("ani_sfx_buzheng_resid_has_hero");
                    }
                    else
                    {
                        ani.Play("ani_sfx_buzheng_resid");
                    }
                    
                }
                controller.SetHeroState(hasHero);
            }
        }

        public void RefreshAllColor()
        {
            for (int i = 0; i < deckCircleControllerList.Count; i++)
            {
                var controller = deckCircleControllerList[i]; 
                controller.SetHeroState(hasDeckSpace[i] >= 0);
            }
        }

        private void RefreshSingleColor(int i)
        {
            var controller = deckCircleControllerList[i]; 
            Animation ani = controller.animation;
            bool hasHero = hasDeckSpace[i] >= 0;
            if (ani)
            {
                ani.Stop();
                if (hasHero)
                {
                    ani.Play("ani_sfx_buzheng_resid_has_hero");
                }
                else
                {
                    ani.Play("ani_sfx_buzheng_resid");
                }
                    
            }
            controller.SetHeroState(hasDeckSpace[i] >= 0);
        }

        public void PlayCircleAni(int idx, string clipName)
        {
            for (int i = 0; i < deckCircleControllerList.Count; i++)
            {
                var ani = deckCircleControllerList[i].animation;
                if (ani)
                {
                    if (i == idx)
                    {
                        ani.Stop();
                        ani.Play(clipName);
                    }
                    else
                    {
                        RefreshSingleColor(i);
                        /*ani.Stop();
                        bool hasHero = hasDeckSpace[i] >= 0;
                        if (hasHero)
                        {
                            ani.Play("ani_sfx_buzheng_resid_has_hero");
                        }
                        else
                        {
                            ani.Play("ani_sfx_buzheng_resid");
                        }*/
                    }
                }
            }
        }

    }
}
